<script>
  import $ from '../dfish.js'
  import {
    h
  } from 'vue'
  import Text from './Text.vue'

  export default {
    name: 'w-spinner',
    mixins: [Text],
    inject: ['provideRangeParent'],
    props: ['decimal', 'format', 'noButton', 'step', 'compare', 'minValue', 'maxValue'],
    methods: {
      x_default() {
        return {
          step: 1,
          inputWidth: 140
        }
      },
      doFormat() {
        if (!this.x.format)
          return;
        let v = this.$refs.v.value
        let s = this.x.format.separator || ','
        let r = RegExp(s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'), 'g')
        let t = $.numFormat(v, this.x.format.length, s, this.x.format.rightward)
        if (v !== t) {
          let n = this.$refs.v.selectionStart
          let b = v.slice(0, n).replace(r, '')
          this.val(t)
          if (document.activeElement === this.$refs.v) {
            let a = t.slice(0, n).replace(r, '')
            $.rngCursor(this.$refs.v, n + (b.length - a.length))
          }
        }
      },
      isBegin() {

      },
      stepBy(a) {
        if (!this.isNormal) return
        let m = this.defaultRuleValue('maxValue')
        let n = this.defaultRuleValue('minValue')
        let u = this.val()
        let v = $.numAdd($.number(u), a * this.x.step)
        let p = this.provideRangeParent && this.provideRangeParent.forms()
        let r = v
        m != null && (r = Math.min(m, r))
        n != null && (r = Math.max(n, r))
        if (p) {
          if (p[0] == this) {
            let endValue = p[1].val()
            if (endValue != null) r = Math.min(endValue, r)
          } else if (p[1] == this) {
            let beginValue = p[0].val()
            if (beginValue != null) r = Math.max(beginValue, r)
          }
        }
        this.warn(false)
        this.focus()
        this.val(r)
        if (r == v) {
          if (this.tip_uid) {
            $.close(this.tip_uid)
            this.tip_uid = null
          }
        } else if (u) {
          // this.showTip({
          //   text: $.loc.form[r < v ? 'step_max_value' : 'step_min_value'],
          //   independent: true,
          // })
        }
      },
      isFocusTarget(el) { // implement
        return this.$refs.btns && this.$refs.btns.contains(el)
      },
      html_button() {
        return h('div', {
          class: 'w-spinner-step w-input-bbr f-flex-column f-oh',
          ref: 'btns'
        }, [
          h('button', {
            class: 'w-spinner-step-btn f-rel',
            disabled: this.x.disabled,
            onclick: e => this.stepBy(1),
            innerHTML: '<i class="f-abs-center f-i f-i-caret-up"></i>'
          }),
          h('button', {
            class: 'w-spinner-step-btn f-rel',
            disabled: this.x.disabled,
            onclick: e => this.stepBy(-1),
            innerHTML: '<i class="f-abs-center f-i f-i-caret-down"></i>'
          }),
        ])
      },
    },
    computed: {
      validHooks() {
        return {
          ...this.pubValidHooks,
          minValue: (v, r, q) => {
            if (v && r != null && r !== '' && ($.isNumber(r) ? ($.number(v) < $.number(r)) : (v < r)))
              return this.formErr(q, [r])
          },
          maxValue: (v, r, q) => {
            if (v && r != null && r !== '' && ($.isNumber(r) ? ($.number(v) > $.number(r)) : (v > r)))
              return this.formErr(q, [r])
          },
          compare: (v, r, q) => {
            if (v && r && c.target && r.mode && this.ownerView) {
              let t = this.ownerView.f(r.target)
              let tv = t && t.formVal()
              if (tv) {
                let d = $.number(v)
                let td = $.number(tv)
                if(!$.eval('d' + c.mode + 'td', {d, td}))
                  return this.formErr(q, [this.getLabelText(), r.mode, t.getLabelText()])
              }
            }
          },
          validateDefault: (v) => {
            this.x.format && (v = v.replace(RegExp(this.x.format.separator || ',', 'g'), ''))
            if (v) {
              if (isNaN(v) || /\s/.test(v))
                return this.formErr({type: 'number_invalid'})
              let d = this.x.decimal
              if (!d && ~v.indexOf('.'))
                return this.formErr({type: 'number_integer'})
              if (d && d > 0 && $.strFrom(v, '.').length > d)
                return this.formErr({type: 'number_decimal_digit'}, [d])
              if (this.provideRangeParent)
                return this.provideRangeParent.getRangeError()
            }
          }
        }
      },
      input_prop() {
        return {
          'w-valuetype': 'number'
        }
      },
    }
  }
</script>

<style>
  .w-spinner-step-btn {
    height: 15px;
    overflow: hidden;
    cursor: pointer;
  }
</style>
